/**
 * 文件名：@AbstractSecurityInterceptor.java <br/>
 * 包名：cn.efunbox.afw.web.security <br/>
 * 项目名：afw-web <br/>
 * @author xtwin <br/>
 */
package cn.efunbox.afw.web.security;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.efunbox.afw.core.exception.SecurityException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * 类名：AbstractSecurityInterceptor  <br />
 *
 * 功能：安全拦截器
 *
 * @author xtwin <br />
 * 创建时间：2016年8月4日 上午9:47:51  <br />
 * @version 2016年8月4日
 */
public abstract class AbstractSecurityInterceptor extends HandlerInterceptorAdapter {
	
	// 日志记录器
	private static final Logger logger = LoggerFactory.getLogger(AbstractSecurityInterceptor.class);
	
	// 忽略options请求，默认为true
	private boolean ignoreOptions = true;

	/**
	 * 功能: <br/>
	 * 
	 * 重写：xtwin <br/>
	 * 
	 * @version ：2016年8月4日 上午9:48:38<br/>
	 * 
	 * @param request
	 * @param response
	 * @param handler
	 * @return
	 * @throws Exception <br/>
	 * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		if (ignoreOptions && HttpMethod.OPTIONS.matches(request.getMethod())) {
			// 忽略options请求
			return true;
		}
		
		try {
			// 执行权限校验
			doSecurity(request, response, handler);
		} catch (SecurityException e) {
			throw e;
		} catch (Exception e) {
			logger.error("security fail : " + String.valueOf(e), e);
			throw new SecurityException("permission.denied", e);
		}
		
		// 权限验证通过
		return true;
	}

	/**
	 * 功能：执行权限处理 <br/>
	 *
	 * @author xtwin <br/>
	 * @version 2016年8月4日 上午9:34:06 <br/>
	 */
	protected abstract void doSecurity(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

	/**
	 * @version 2016年8月26日-下午5:22:12
	 */
	public void setIgnoreOptions(boolean ignoreOptions) {
		this.ignoreOptions = ignoreOptions;
	}
}
